/*
 * XBee.h
 
 This file is part of Foobar.

 Foobar is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 Foobar is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 
 * Created: 12/13/2013 2:43:55 AM
 *  Author: Tim
 */ 


#ifndef XBEE_H_
#define XBEE_H_

#include "../board/board.h"

//setups CTS line for use
#define XBee_CTS_INIT()			(XBee_PORT_CTS.DIRSET = XBee_CTS_PINMSK)
#define XBee_CTS_ASSERT()		(XBee_PORT_CTS.OUTSET = XBee_CTS_PINMSK)
#define XBee_CTS_ASSERT_n()		(XBee_PORT_CTS.OUTCLR = XBee_CTS_PINMSK)


//RTS READ FLAG
#define XBee_RTS_ASSERTED_n	(XBee_PORT_RTS.IN & XBee_RTS_PINMSK)
#define XBee_RTS_ASSERTED	(!XBee_RTS_ASSERTED_n)

#define strToNum(a,b) (a<<8 + b)

#define XBee_Start_Delimiter			0x7E

typedef enum AT_COMMAND
{
	//Addressing
	AT_Desination_Address_High			= strToNum('D','H'),
	AT_Desination_Address_Low			= strToNum('D','L'),
	AT__16_bit_Network_Address			= strToNum('M','Y'),
	AT__16_bit_Parent_Network_Address	= strToNum('M','P'),
	AT_Number_of_Remaining_Children		= strToNum('N','C'),
	AT_Serial_Number_High				= strToNum('S','H'),
	AT_Serial_Number_Low				= strToNum('S','L'),
	AT_Node_Identifier					= strToNum('N','I'),
	AT_Source_Endpoint					= strToNum('S','E'),
	AT_Destination_Endpoint				= strToNum('D','E'),
	AT_Cluster_Identifier				= strToNum('C','I'),
	AT_Maximum_RF_Payload_Bytes			= strToNum('N','P'),
	AT_Device_Type_Identifier			= strToNum('D','D'),
	AT_Operating_Channel				= strToNum('C','H'),
	AT_Extend_PAN_ID					= strToNum('I','D'),
	AT_OPerating_Extended_PAN_ID		= strToNum('O','P'),
	AT_Maximum_Unicast_Hops				= strToNum('N','H'),
	AT_Broadcast_Hops					= strToNum('B','H'),
	AT_Operating_16_bit_PAN_ID			= strToNum('O','I'),
	AT_Node_Discovery_Options			= strToNum('N','T'),
	AT_Scan_Channels					= strToNum('S','C'),
	AT_Scan_Duration					= strToNum('S','D'),
	AT_ZigBee_Stack_Profile				= strToNum('Z','S'),
	
	//Networking
	AT_Node_Join_Time					= strToNum('N','J'),
	AT_Channel_Verification				= strToNum('J','V'),
	AT_Network_Watchdog_Timeout			= strToNum('N','W'),
	AT_Join_Notification				= strToNum('J','N'),
	AT_Aggregate_Routing_Notification	= strToNum('A','R'),
	
	//Securtiy
	AT_Encryption_Enable				= strToNum('E','E'),
	AT_Encryption_Options				= strToNum('E','O'),
	AT_Network_Encryption_Key			= strToNum('N','K'),
	AT_Link_Key							= strToNum('K','Y'),
	
	//RF Interfacing
	AT_Power_Level						= strToNum('P','L'),
	AT_Power_Mode						= strToNum('P','M'),
	AT_Received_Signal_Strength			= strToNum('D','B'),
	AT_Peak_Power						= strToNum('P','P'),
	
	//Serial Interfacing I/O
	AT_API_Enable						= strToNum('A','P'),
	AT_API_Options						= strToNum('A','O'),
	AT_INterface_Data_Rate				= strToNum('B','D'),
	AT_Serial_Partity					= strToNum('N','B'),
	AT_Stop_Bits						= strToNum('S','B'),
	AT_Packetization_Timeout			= strToNum('R','O'),
	AT_DIO7_Configuration				= strToNum('D','7'),
	AT_DIO6_Configuration				= strToNum('D','6'),
	
	//I/O Commands	
	AT_IO_Sample_Rate					= strToNum('I','R'),
	AT_IO_Data_Change_Detection			= strToNum('I','C'),
	AT_PWM0_Configuration				= strToNum('P','0'),
	AT_DIO11_Configuration				= strToNum('P','1'),
	AT_DIO12_Configuration				= strToNum('P','2'),
	AT_DIO13_Configuration				= strToNum('P','3'),
	AT_AD0_DIO0_Configuration			= strToNum('D','0'),
	AT_AD1_DIO1_Configuration			= strToNum('D','1'),
	AT_AD2_DIO2_Configuration			= strToNum('D','2'),
	AT_AD3_DIO3_Configuration			= strToNum('D','3'),
	AT_DIO4_Configuration				= strToNum('D','4'),
	AT_DIO5_Configuration				= strToNum('D','5'),
	AT_DIO8_Configuration				= strToNum('D','5'),
	AT_Assoc_LED_Blink_Time				= strToNum('L','T'),
	AT_Pull_up_Resistor					= strToNum('P','R'),
	AT_RSSI_PWM_Timer					= strToNum('R','P'),
	AT_Supply_Voltage					= strToNum('%','V'),
	AT_Voltage_Supply_Monitoring		= strToNum('V','+'),
	AT_Read_Temperature					= strToNum('T','P'),
	
	//Diagnostics
	AT_Firmware_Version					= strToNum('V','R'),
	AT_Hardware_Version					= strToNum('H','V'),
	AT_Association_Indication			= strToNum('A','I'),
	
	//AT Command Options
	AT_Command_Mode_Timeout				= strToNum('C','T'),
	AT_Exit_Command_Mode				= strToNum('C','N'),
	AT_Guard_Times						= strToNum('G','T'),
	AT_Command_Sequence_character		= strToNum('C','C'),
	
	//Sleeps Commands
	AT_Sleep_Mode						= strToNum('S','M'),
	AT_Number_of_Sleep_Periods			= strToNum('S','N'),
	AT_Sleep_Period						= strToNum('S','P'),
	AT_Time_Before_Sleep				= strToNum('S','T'),
	AT_Sleep_Options					= strToNum('S','O'),
	AT_Wake_Host						= strToNum('W','H'),
	AT_Sleep_Immediately				= strToNum('S','I'),
	AT_Polling_Rate						= strToNum('P','O'),
	
	//Execution Commands
	AT_Apply_Changes					= strToNum('A','C'),
	AT_Write							= strToNum('W','R'),
	AT_Restore_Defaults					= strToNum('R','E'),
	AT_Software_Reset					= strToNum('F','R'),
	AT_Network_Reset					= strToNum('N','R'),
//	AT_Sleep_Immediately				= strToNum('S','I'),
	AT_Commissioning_Pushbutton			= strToNum('C','B'),
}AT_Command_t;


typedef enum FRAME_ENUM
{
	AT_Command_enum									= 0x08,
	AT_Command_Queue_Parameter_Value_enum			= 0x09,
	ZigBee_Transmit_Request_enum					= 0x10,
	Explicit_Addressing_ZigBee_Command_Frame_enum	= 0x11,
	Remote_Command_Request_enum						= 0x17,
	Create_Source_Route_enum						= 0x21,
	AT_Command_Response_enum						= 0x88,
	Modem_Status_enum								= 0x8A,
	ZigBee_Transmit_Status_enum						= 0x8B,
	ZigBee_Receive_Packet_enum 						= 0x90,
	ZigBee_Explicit_Rx_Indicator_enum				= 0x91,
	ZigBee_IO_Data_Sample_Rx_Indicator_enum			= 0x92,
	XBee_Sensor_Read_Indicator_enum					= 0x94,
	Node_Identification_Indicator_enum				= 0x95,
	Remote_Command_Response_enum					= 0x97,
	Over_the_Air_Firmware_Update_Status_enum		= 0xA0,
	Route_Record_Indicator_enum						= 0xA1,
	Many_to_One_Route_Request_Indicator_enum		= 0xA3
}frame_t;

typedef struct LENGTH
{
	uint16_t LSB	:8;
	uint16_t MSB	:8;
}length_t;

typedef struct API_AT_Command_pkt
{
	uint8_t			startDelimiter;
	length_t		length;
	frame_t			frame_ID;
	AT_Command_t	AT_Command;
	uint8_t			checkSum;
}API_AT_Command_t;

typedef struct AT_Command_Queue_Parameter_Value_pkt
{
	uint8_t			startDelimiter;
	length_t		length;
	frame_t			frame_Type;
	uint8_t			frame_ID;
	AT_Command_t	AT_Command;
	uint8_t			param;
	uint8_t			checkSum;
}AT_Command_Queue_Parameter_Value_t;

typedef struct ZigBee_Transmit_Request_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		frame_ID;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		broadcastRadius;
	uint8_t		options;
	uint8_t		RF_Data[8];
	uint8_t		checkSum;
}ZigBee_Transmit_Request_t;

typedef struct Explicit_Addressing_ZigBee_Command_Frame_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		frame_ID;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		sourceEndpoint;
	uint8_t		destinationEndpoint;
	uint16_t	clusterID;
	uint16_t	profileID;
	uint8_t		broadcastRadius;
	uint8_t		transmitOptions;
	uint8_t		dataPayload[6];
	uint8_t		checkSum;
}Explicit_Addressing_ZigBee_Command_Frame_pkt;

typedef struct Remote_Command_Request_pkt
{
	uint8_t			startDelimiter;
	length_t		length;
	frame_t			frame_Type;
	uint8_t			frame_ID;
	uint8_t			Addr_64[8];
	uint8_t			Addr_16[2];
	uint8_t			remoteCommandOptions;
	AT_Command_t	AT_Command;
	uint8_t			commandParameter;
	uint8_t			checkSum;	
}Remote_Command_Request_t;

typedef struct Create_Source_Route_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		frame_ID;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		routeCommandOptions;
	uint8_t		numberOfAddresses;
	uint16_t	*addresses;	//I believe the depth should not just be three
	uint8_t		checkSum;
}Create_Source_Route_t;

typedef struct AT_Command_Response_pkt
{
	uint8_t			startDelimiter;
	length_t		length;
	frame_t			frame_Type;
	uint8_t			frame_ID;
	AT_Command_t	AT_Command;
	uint8_t			CommandStatus;
	uint8_t			*CommandData;
	uint8_t			checkSum;
}AT_Command_Response_t;

typedef struct Modem_Status_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		status;
	uint8_t		checkSum;
}Modem_Status_t;

typedef struct ZigBee_Transmit_Status_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		frame_ID;
	uint16_t	destinationAddr;
	uint8_t		transmitRetryCnt;
	uint8_t		deliveryStatus;
	uint8_t		discoveryStatus;
	uint8_t		checkSum;
}ZigBee_Transmit_Status_t;

typedef struct ZigBee_Receive_Packet_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		frame_ID;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		receiveOptions;
	uint8_t		*receiveData;
	uint8_t		checkSum;
}ZigBee_Receive_Packet_t;

typedef struct ZigBee_Explicit_Rx_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		sourceEndpoint;
	uint8_t		destinationEndpoint;
	uint16_t	clusterID;
	uint16_t	profileID;
	uint8_t		receiveOptions;
	uint8_t		*receiveData;
	uint8_t		checkSum;
}ZigBee_Explicit_Rx_Indicator_t;

typedef struct ZigBee_IO_Data_Sample_Rx_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		receiveOptions;
	uint8_t		numberOfSamples;
	uint16_t	digitalChannelMsk;
	uint16_t	analogChannelMsk;
	uint8_t		digitalSamples;
	uint16_t	analogSample;
	uint8_t		checkSum;
}ZigBee_IO_Data_Sample_Rx_Indicator_t;

typedef struct XBee_Sensor_Read_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		Addr_64[8];
	uint8_t		Addr_16[2];
	uint8_t		receiveOptions;
	uint8_t		oneWireSensors;
	uint8_t		AD_values[8];
	uint16_t	temperatureRead;
	uint8_t		checkSum;
}XBee_Sensor_Read_Indicator_t;

typedef struct Node_Identification_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		Addr_64_src[8];
	uint8_t		Addr_16_net[2];
	uint8_t		receiveOptions;
	uint8_t		Addr_16_src[2];
	uint8_t		Addr_64_net[8];
	uint8_t		*NI_sting;
	uint8_t		terminator;
	uint8_t		Addr_16_par[2];
	uint8_t		deviceType;
	uint8_t		sourceEvent;
	uint16_t	digiProfileID;
	uint16_t	manufacturerID;
	uint8_t		checkSum;
}Node_Identification_Indicator_t;

typedef struct Remote_Command_Response_pkt
{
	uint8_t			startDelimiter;
	length_t		length;
	frame_t			frame_Type;
	uint8_t			frameID;
	uint8_t			Addr_64_src[8];
	uint8_t			Addr_16_src_rem[2];
	AT_Command_t	AT_Command;
	uint8_t			commandStatus;
	uint8_t			*commandData;
	uint8_t			checkSum;
}Remote_Command_Response_t;

typedef struct Over_the_Air_Firmware_Update_Status_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		checkSum;
}Over_the_Air_Firmware_Update_Status_t;

typedef struct Route_Record_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		checkSum;
}Route_Record_Indicator_t;

typedef struct Many_to_One_Route_Request_Indicator_pkt
{
	uint8_t		startDelimiter;
	length_t	length;
	frame_t		frame_Type;
	uint8_t		checkSum;
}Many_to_One_Route_Request_Indicator_t;
	
#endif /* XBEE_H_ */